/*
 * Copyright 2006 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.user.rebind.rpc;

import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.TypeOracle;

class Shared {
  static final String ASYNC_CALLBACK_INTERFACE_NAME = "com.google.gwt.user.client.rpc.AsyncCallback";
  
  static final String ENTRY_POINT_TAG = "gwt.defaultEntryPoint";
  
  static final String SERIALIZATION_EXCEPTION_CLASS_NAME = "com.google.gwt.user.client.rpc.SerializationException";

  static final String DEFAULT_BUILTIN_CUSTOM_SERIALIZER_PACKAGE_NAME = "com.google.gwt.user.client.rpc.core.java.lang";

  static final String TYPE_SERIALIZER_SUFFIX = "_TypeSerializer";

  /**
   * Property used to control whether or not the RPC system will enforce the
   * versioning scheme or not.
   */
  static final String RPC_PROP_ENFORCE_TYPE_VERSIONING = "gwt.enforceRPCTypeVersioning";

  /**
   * Suffix for generated field serializers
   */
  static final String GENERATED_FIELD_SERIALIZER_SUFFIX = "_FieldSerializer";

  /**
   * Suffix for Custom Field Serializers
   */
  static final String CUSTOM_FIELD_SERIALIZER_SUFFIX = "_CustomFieldSerializer";

  /**
   * Cannot use IsSerializable.class.getName() here because these classes may
   * not be compiled.
   */
  static final String SERIALIZABLE_MARKER_INTERFACE_NAME = "com.google.gwt.user.client.rpc.IsSerializable";

  static final String SERIALIZATION_STREAM_CLASS_NAME = "com.google.gwt.user.client.rpc.SerializationStream";

  static final String SERIALIZATION_STREAM_READER_INTERFACE_NAME = "com.google.gwt.user.client.rpc.SerializationStreamReader";

  static final String SERIALIZATION_STREAM_WRITER_INTERFACE_NAME = "com.google.gwt.user.client.rpc.SerializationStreamWriter";

  static final String SERIALIZATION_STREAM_OBJECT_DECODER_INTERFACE_NAME = "com.google.gwt.user.client.rpc.SerializationStreamObjectDecoder";

  static final String SERIALIZATION_STREAM_OBJECT_ENCODER_INTERFACE_NAME = "com.google.gwt.user.client.rpc.SerializationStreamObjectEncoder";

  static final String SERIALIZER_DESERIALIZE_METHOD_NAME = "deserialize";

  static final String SERIALIZER_INSTANTIATE_METHOD_NAME = "instantiate";

  static final String SERIALIZER_SERIALIZE_METHOD_NAME = "serialize";

  /**
   * Computes a good name for a class related to the specified type, such that
   * the computed name can be a top-level class in the same package as the
   * specified type.
   * 
   * <p>
   * This method does not currently check for collisions between the synthesized
   * name and an existing top-level type in the same package. It is actually
   * tricky to do so, because on subsequent runs, we'll view our own generated
   * classes as collisions. There's probably some trick we can use in the future
   * to make it totally bulletproof.
   * </p>
   * 
   * @param type the name of the base type, whose name will be built upon to
   *          synthesize a new type name
   * @param suffix a suffix to be used to make the new synthesized type name
   * @return an array of length 2 such that the first element is the package
   *         name and the second element is the synthesized class name
   */
  static String[] synthesizeTopLevelClassName(JClassType type, String suffix) {
    // Gets the basic name of the type. If it's a nested type, the type name
    // will contains dots.
    //
    String className = type.getName();

    // Add the meaningful suffix.
    //
    className += suffix;

    // Make it a top-level name.
    //
    className = className.replace('.', '_');

    String packageName = type.getPackage().getName();
    TypeOracle typeOracle = type.getOracle();

    return new String[]{packageName, className};
  }
}
